001 package net.sf.xdc.processing;
002
003 /*
004 * Copyright 2005-2006 Jens Voß.
005 *
006 * Licensed under the GNU Lesser General Public License (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://opensource.org/licenses/lgpl-license.php
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 import java.io.BufferedReader;
020 import java.io.File;
021 import java.io.IOException;
022 import java.io.Writer;
023 import java.io.FileNotFoundException;
024 import java.text.NumberFormat;
025 import java.util.StringTokenizer;
026 import java.nio.charset.Charset;
027
028 import net.sf.xdc.util.Logging;
029 import net.sf.xdc.util.IOUtils;
030 import org.apache.log4j.Logger;
031
032 /**
033 * This class is responsible for generating HTML pages containing the
034 * contents of XML source files (in HTML format), decorated with line numbers
035 * and named anchors (enumerated by the current line numbers).
036 *
037 * @author Jens Voß
038 * @since 0.5
039 * @version 0.5
040 */
041 public class SourceProcessor {
042
043 private static final Logger LOG = Logging.getLogger();
044 private static final NumberFormat NF = NumberFormat.getIntegerInstance();
045
046 private static String escapeXml(String str) {
047 return str.replaceAll("&", "&").replaceAll("\"", """)
048 .replaceAll("<", "<").replaceAll(">", ">");
049 }
050
051 private File outDir;
052
053 /**
054 * Public constructor.
055 *
056 * @param outDir The output directory for this <code>SourceProcessor</code>
057 */
058 public SourceProcessor(File outDir) {
059 this.outDir = new File(outDir, "src-html");
060 this.outDir.mkdirs();
061 }
062
063 /**
064 * This method is responsible for generating the HTML version of the source
065 * file specified by the <code>source</code> parameter.
066 *
067 * @param source The <code>XdcSource</code> object for which source HTML is
068 * generated
069 * @param sourceEncoding The <code>Charset</code> used for interpreting the
070 * source file
071 * @param targetEncoding The <code>Charset</code> used for writing to the
072 * output file
073 */
074 public void processSource(XdcSource source, Charset sourceEncoding, Charset targetEncoding) {
075
076 File dir = new File(outDir, source.getPackageName());
077 dir.mkdirs();
078 BufferedReader in = null;
079 Writer out = null;
080 try {
081
082 in = new BufferedReader(IOUtils.getReader(source.getFile(), sourceEncoding));
083 int lineNo = 0;
084 while (in.readLine() != null) {
085 lineNo++;
086 }
087 in.close();
088 in = null;
089
090 int length = String.valueOf(lineNo).length();
091 NF.setMinimumIntegerDigits(length);
092 NF.setGroupingUsed(false);
093
094 in = new BufferedReader(IOUtils.getReader(source.getFile(), sourceEncoding));
095
096 out = IOUtils.getWriter(new File(dir, source.getFile().getName() + ".html"), targetEncoding);
097 out.write("<html><head><link href=\"");
098 StringTokenizer tok = new StringTokenizer(source.getPackageName(), "/.", false);
099 while (tok.hasMoreTokens()) {
100 tok.nextToken();
101 out.write("../");
102 }
103 out.write("stylesheet.css\" rel=\"stylesheet\" type=\"text/css\">");
104 out.write("</head><body><pre style=\"font-size:10pt;padding-bottom:1000px;\">\n");
105
106 lineNo = 0;
107 String line;
108 while ((line = in.readLine()) != null) {
109 lineNo++;
110 out.write("<a name=\"line");
111 out.write(String.valueOf(lineNo));
112 out.write("\"/>");
113 out.write("<font color=\"green\"> ");
114 out.write(NF.format(lineNo));
115 out.write(" </font> ");
116 out.write(escapeXml(line));
117 out.write('\n');
118 }
119 out.write("</pre></body></html>");
120 }
121 catch (FileNotFoundException e) {
122 LOG.error(e.getMessage(), e);
123 }
124 catch (IOException e) {
125 LOG.error(e.getMessage(), e);
126 }
127 finally {
128 try {
129 if (in != null) {
130 in.close();
131 }
132 if (out != null) {
133 out.close();
134 }
135 }
136 catch (IOException e) {
137 LOG.error(e.getMessage(), e);
138 }
139 }
140 }
141
142 }